Skip to content

Method: addAttributeDescriptor(Field, Descriptor)

1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.jopa.model.descriptors;
16:
17: import cz.cvut.kbss.jopa.model.metamodel.Attribute;
18: import cz.cvut.kbss.jopa.model.metamodel.Attribute.PersistentAttributeType;
19: import cz.cvut.kbss.jopa.model.metamodel.FieldSpecification;
20: import cz.cvut.kbss.jopa.utils.ErrorUtils;
21:
22: import java.lang.reflect.Field;
23: import java.net.URI;
24: import java.util.*;
25: import java.util.Map.Entry;
26:
27: /**
28: * Describes an entity.
29: * <p>
30: * Each attribute has a descriptor associated with it.
31: */
32: public class EntityDescriptor extends Descriptor {
33:
34: private final Map<Field, Descriptor> fieldDescriptors;
35:
36: public EntityDescriptor() {
37: this.fieldDescriptors = new HashMap<>();
38: }
39:
40: /**
41: * Allows to configure where object property assertions should be stored
42: *
43: * @param assertionsInSubjectContext Whether object property assertions are stored in the subject's. Defaults to
44: * {@code true}. If {@code false}, object property assertions are stored in the
45: * object's context
46: * @see #areAssertionsInSubjectContext()
47: */
48: public EntityDescriptor(boolean assertionsInSubjectContext) {
49: super(assertionsInSubjectContext);
50: this.fieldDescriptors = new HashMap<>();
51: }
52:
53: public EntityDescriptor(URI context) {
54: super(context);
55: this.fieldDescriptors = new HashMap<>();
56: }
57:
58: public EntityDescriptor(URI context, boolean assertionsInSubjectContext) {
59: super(context, assertionsInSubjectContext);
60: this.fieldDescriptors = new HashMap<>();
61: }
62:
63: @Override
64: public EntityDescriptor addAttributeDescriptor(Field attribute, Descriptor descriptor) {
65: Objects.requireNonNull(attribute, ErrorUtils.getNPXMessageSupplier("attribute"));
66: Objects.requireNonNull(descriptor, ErrorUtils.getNPXMessageSupplier("descriptor"));
67:
68: fieldDescriptors.put(attribute, descriptor);
69: return this;
70: }
71:
72: @Override
73: public EntityDescriptor addAttributeContext(Field attribute, URI context) {
74: Objects.requireNonNull(attribute, ErrorUtils.getNPXMessageSupplier("attribute"));
75:
76: fieldDescriptors.put(attribute, new FieldDescriptor(context, attribute));
77: return this;
78: }
79:
80: @Override
81: public EntityDescriptor setLanguage(String languageTag) {
82: super.setLanguage(languageTag);
83: fieldDescriptors.values().forEach(d -> d.setLanguage(languageTag));
84: return this;
85: }
86:
87: @Override
88: public EntityDescriptor setAttributeLanguage(Field attribute, String languageTag) {
89: Objects.requireNonNull(attribute);
90:
91: fieldDescriptors.putIfAbsent(attribute, new FieldDescriptor(null, attribute));
92: fieldDescriptors.get(attribute).setLanguage(languageTag);
93: return this;
94: }
95:
96: @Override
97: public Descriptor getAttributeDescriptor(FieldSpecification<?, ?> attribute) {
98: Objects.requireNonNull(attribute);
99: Descriptor d = getFieldDescriptor(attribute.getJavaField());
100: if (d == null) {
101: d = createDescriptor(attribute, context);
102: if (hasLanguage()) {
103: d.setLanguage(getLanguage());
104: }
105: }
106: return d;
107: }
108:
109: @Override
110: public URI getAttributeContext(FieldSpecification<?, ?> attribute) {
111: Objects.requireNonNull(attribute);
112: final Descriptor attDescriptor = getAttributeDescriptor(attribute);
113: return attDescriptor.overridesAssertionsInSubjectContext() || !assertionsInSubjectContext ?
114: attDescriptor.getContext() : getContext();
115: }
116:
117: @Override
118: public Collection<Descriptor> getAttributeDescriptors() {
119: return Collections.unmodifiableCollection(fieldDescriptors.values());
120: }
121:
122: private Descriptor getFieldDescriptor(Field field) {
123: for (Entry<Field, Descriptor> e : fieldDescriptors.entrySet()) {
124: if (e.getKey().equals(field)) {
125: return e.getValue();
126: }
127: }
128: return null;
129: }
130:
131: private static Descriptor createDescriptor(FieldSpecification<?, ?> att, URI context) {
132: if (att instanceof Attribute) {
133: final Attribute<?, ?> attSpec = (Attribute<?, ?>) att;
134: if (attSpec.getPersistentAttributeType() == PersistentAttributeType.OBJECT) {
135: if (attSpec.isCollection()) {
136: return new ObjectPropertyCollectionDescriptor(context, att.getJavaField());
137: } else {
138: return new EntityDescriptor(context);
139: }
140: }
141: }
142: return new FieldDescriptor(context, att.getJavaField());
143: }
144:
145: @Override
146: protected Set<URI> getContextsInternal(Set<URI> contexts, Set<Descriptor> visited) {
147: if (visited.contains(this)) {
148: return contexts;
149: }
150: if (context == null) {
151: return null;
152: }
153: contexts.add(context);
154: visited.add(this);
155: for (Descriptor fd : fieldDescriptors.values()) {
156: contexts = fd.getContextsInternal(contexts, visited);
157: if (contexts == null) {
158: return null;
159: }
160: }
161: return contexts;
162: }
163:
164: @Override
165: public boolean equals(Object o) {
166: if (this == o) {
167: return true;
168: }
169: if (!(o instanceof EntityDescriptor)) {
170: return false;
171: }
172: if (!super.equals(o)) {
173: return false;
174: }
175:
176: EntityDescriptor that = (EntityDescriptor) o;
177:
178: if (fieldDescriptors.size() != that.fieldDescriptors.size()) {
179: return false;
180: }
181: for (Entry<Field, Descriptor> e : fieldDescriptors.entrySet()) {
182: if (e.getValue() == null) {
183: if (that.fieldDescriptors.containsKey(e.getKey()) && that.fieldDescriptors.get(e.getKey()) != null) {
184: return false;
185: }
186: } else {
187: if (e.getValue() == this && that.fieldDescriptors.get(e.getKey()) == that) {
188: continue;
189: }
190: if (!e.getValue().equals(that.fieldDescriptors.get(e.getKey()))) {
191: return false;
192: }
193: }
194: }
195: return true;
196: }
197:
198: @Override
199: public int hashCode() {
200: int result = super.hashCode();
201: result = 31 * result + (fieldDescriptors != null ? fieldDescriptors.entrySet().stream()
202: .map(e -> e.getKey().hashCode() ^
203: (e.getValue() == this ? 0 :
204: e.getValue().hashCode())).reduce(0,
205: Integer::sum) : 0);
206: return result;
207: }
208: }